import openpyxl,configparser,csv,glob,os,time,shutil,re,datetime,subprocess,sys
from  datetime import timedelta
from Evtx.Evtx import Evtx
import xml.etree.ElementTree as ET
error_code={"Bsod":"0x002757","Bsod0X9F":"0x002722","Bsod0XD1":"0x002723","Bsod0X7B":"0x002724","Bsod0X0A":"0x002725","Bsod0X50":"0x002726","Bsod0XE2":"0x002727","Bsod0X1E":"0x002728","Bsod0X3B":"0x00273B","Bsod0X7E":"0x00273C","Bsod0X7F":"0x00273D","Bsod0X7A":"0x00273E","Bsod0X154":"0x00273F","Bsod0XEF":"0x002740","Bsod0X24":"0x002741","Bsod0X124":"0x002742","Bsod0X113":"0x002743","Bsod0X114":"0x002744","Bsod0X116":"0x002745","Bsod0X117":"0x002746","Bsod0X119":"0x002747","Bsod0X10E":"0x002748","Bsod0XEA":"0x002749","Bsod0X19":"0x00274A","Bsod0XC2":"0x00274B","Bsod0XC5":"0x00274C","Bsod0X1A":"0x00274D","Bsod0X4E":"0x00274E","Bsod0X139":"0x00274F","Bsod0X133":"0x002750","Bsod0X109":"0x002751","Bsod0X1D1":"0x002752","Bsod0X1D3":"0x002753","Bsod0XB8":"0x002754","Bsod0X101":"0x002755","Bsod0X13A":"0x002756"}
class log:
    def __init__(self):
        self.current_tool_path=os.path.dirname(os.path.abspath(sys.argv[0]))#获取当前路径的绝对路径,返回比如log.exe放在D盘dist里就返回放在D:\items\LNB_ATS\dist，os.path.dirname(path) 是一个简单的路径分割工具，用于提取父目录路径,sys.argv 是一个列表，包含命令行参数，sys.argv[0] 是脚本名称（可能是相对路径或仅文件名），os.path.abspath()将路径转换为绝对路径
        base_path = os.path.join(self.current_tool_path, 'output')#找到wiLR output文件夹
        random_dirs = glob.glob(os.path.join(base_path, "[0-9]*"))  # 匹配所有由数字组成的目录名，这里返回列表，Python 的 glob 模块主要用于 文件路径匹配，它支持使用通配符（如 *, ?, []）来查找符合特定模式的文件或目录。[0-9]：匹配任意一个数字字符(0-9)，*：匹配任意数量的任意字符(包括无字符),因此"[0-9]*"匹配的是：以数字开头，后跟任意字符(或无字符)的文件名
        target_path = os.path.join(random_dirs[0], "Job0", "TestSummary.ini")
        target_path_1 = os.path.join(random_dirs[0], "Job0", "DeviceStatus.ini")
        self.info = configparser.ConfigParser()#读取ini文件的固定用法
        self.info.read(os.path.join(self.current_tool_path, 'info.ini'),encoding='utf-8')
        self.TestSummary = configparser.ConfigParser()  # 读取ini文件的固定用法, 这里分开写避免混淆
        with open(target_path, 'rb') as f:#以2进制读取，因为tool之前有报错读取sumary.ini fail，0x00/0x00/0x00 查询时因为这个ini文件里有大量空字符0x00,所以想法先取消空字符
            content = f.read()
        content = content.replace(b'\x00', b'').decode('utf-8')#处理字节数据并将其转换为字符串，将字节数据中的所有空字符(\x00)替换为空字节(b'')，即删除所有空字符，这在处理二进制数据时很常见，因为某些二进制格式可能包含无意义的空填充字符，将处理后的字节数据(bytes)解码为UTF-8编码的字符串
        self.TestSummary.read_string(content)#读取ini格式的字符串内容， TestSummary.read时直接读取配置文件，不影响后续操作
        # self.TestSummary.read(target_path,encoding='utf-8')  # 读取文件，C:\Users\7\Desktop\wiLongRun\output\250523144323\Job0\TestSummary.ini
        self.device_check_total = openpyxl.load_workbook(os.path.join(self.current_tool_path, 'device_check_total.xlsx'))
        self.sheet_device = self.device_check_total.worksheets[0]  # 索引0表示第一个工作表 # 获取第一个工作表（默认工作表）
        self.overview_result = openpyxl.load_workbook(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
        self.sheet_over = self.overview_result.worksheets[0]
        self.devicestatus = configparser.ConfigParser()
        # with open(target_path_1, 'rb') as f1:
        #     content1 = f1.read()
        # try:
        #     content1 = content1.replace(b'\x00', b'').decode('utf-8',errors='ignore')
        # except:
        #     pass
        # self.devicestatus.read_string(content1)
        try:
            self.devicestatus.read(target_path_1)#暂没遇到这个配置文件0x00报错，所以先采用这种方式读取
        except:
            pass

    def log_standard(self):
        maxloopresult=self.info.get('config','maxloopresult')#这里假如maxloopresult的是loop6.result
        if self.TestSummary.has_option('Cycle 1', maxloopresult) and self.TestSummary.has_option('Cycle 1', 'JobResult'):#如果loop6.result和JobResult都有，代表有了最终的结果，而且圈数也是按设置的圈数跑完了的, 不存在黑屏蓝屏hang等异常
            JobResult=self.TestSummary.get('Cycle 1','JobResult')
            if JobResult=='PASS':#JobResult=PASS，代表这个job最终pass，那倒推肯定每一圈都pass,收集最终结果传入result文件夹
                target_cell=self.sheet_device.cell(column=1, row=1)
                target_cell.value='No'
                target_cell = self.sheet_device.cell(column=2, row=1)
                target_cell.value = 'State'
                target_cell = self.sheet_device.cell(column=3, row=1)
                target_cell.value = 'Name'
                self.device_check_total.save(os.path.join(self.current_tool_path, 'device_check_total.xlsx'))#都pass所以什么都不用填
                target_cell = self.sheet_over.cell(column=1, row=1)
                target_cell.value = 'Subitem'
                target_cell = self.sheet_over.cell(column=2, row=1)
                target_cell.value = 'No'
                target_cell = self.sheet_over.cell(column=3, row=1)
                target_cell.value = 'State'
                target_cell = self.sheet_over.cell(column=4, row=1)
                target_cell.value = 'ErrorCode'
                target_cell = self.sheet_over.cell(column=5, row=1)
                target_cell.value = 'ErrorDesc'
                target_cell = self.sheet_over.cell(column=6, row=1)
                target_cell.value = 'Begin'
                target_cell = self.sheet_over.cell(column=7, row=1)
                target_cell.value = 'End'
                for eachcycle in range (2,self.info.getint('config','cycle')+2):#从第2行开始写，比如一共6圈，结果就是2，3，4，5，6，7行有数据，就是range(2,6+2)遍历2到7行
                    target_cell = self.sheet_over.cell(column=1, row=eachcycle)#第一列写PM类型
                    target_cell.value=self.info.get('config','pmclass')
                    target_cell = self.sheet_over.cell(column=2, row=eachcycle)  # 第二列写cycle圈数，第一圈开始
                    target_cell.value = str(eachcycle-1)
                    target_cell = self.sheet_over.cell(column=3, row=eachcycle)  # 第三列写结果，这里都是pass,因为前置条件pass了已经
                    target_cell.value ='PASS'
                    target_cell = self.sheet_over.cell(column=6, row=eachcycle)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                    begin_time=self.TestSummary.get('Cycle 1',f'Loop{eachcycle-2}.StartDateTime')#第一圈开始时间对应Loop0.StartDateTime
                    target_cell.value = begin_time
                    target_cell = self.sheet_over.cell(column=7, row=eachcycle)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                    end_time = self.TestSummary.get('Cycle 1', f'Loop{eachcycle - 2}.EndDateTime')  # 第一圈开始时间对应Loop0.StartDateTime
                    target_cell.value = end_time
                self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
            else:#结果不为pass，又跑完了圈数，就是设备管理器异常，跑了6圈，结果会生成0到6圈的，其中1到6是device check的结果， 0-5是跑完6圈来回时间，loop3.result=pass。代表第3圈设备检查pass，但是实际4圈跑完有回到OS了，正在进行第4圈设备检查和第5圈的开始准备
                target_cell = self.sheet_over.cell(column=1, row=1)
                target_cell.value = 'Subitem'
                target_cell = self.sheet_over.cell(column=2, row=1)
                target_cell.value = 'No'
                target_cell = self.sheet_over.cell(column=3, row=1)
                target_cell.value = 'State'
                target_cell = self.sheet_over.cell(column=4, row=1)
                target_cell.value = 'ErrorCode'
                target_cell = self.sheet_over.cell(column=5, row=1)
                target_cell.value = 'ErrorDesc'
                target_cell = self.sheet_over.cell(column=6, row=1)
                target_cell.value = 'Begin'
                target_cell = self.sheet_over.cell(column=7, row=1)
                target_cell.value = 'End'
                for eachcycle in range(2, self.info.getint('config', 'cycle') + 2):  # 从第2行开始写，比如一共6圈，结果就是2，3，4，5，6,7行有数据，就是range(2,6+2)遍历2到7行
                    target_cell = self.sheet_over.cell(column=1, row=eachcycle)  # 第一列写PM类型
                    target_cell.value = self.info.get('config', 'pmclass')
                    target_cell = self.sheet_over.cell(column=2, row=eachcycle)  # 第二列写cycle圈数，第一圈开始
                    target_cell.value = str(eachcycle - 1)
                    target_cell = self.sheet_over.cell(column=3, row=eachcycle)  # 第三列写结果，
                    if self.TestSummary.get('Cycle 1',f'Loop{eachcycle-1}.Result')=='FAIL':#loop 0必定是pass，不纳入设备检查圈数，作为初始环境的标杆，后面的圈数和她对比
                        target_cell.value = 'FAIL'
                        target_cell = self.sheet_over.cell(column=4, row=eachcycle)
                        target_cell.value='0x002761'
                        target_cell = self.sheet_over.cell(column=5, row=eachcycle)
                        target_cell.value = 'AbnormalEquipmentStatus'
                    else:
                        target_cell.value='PASS'
                    target_cell = self.sheet_over.cell(column=6, row=eachcycle)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                    begin_time = self.TestSummary.get('Cycle 1', f'Loop{eachcycle - 2}.StartDateTime')  # 第一圈开始时间对应Loop0.StartDateTime
                    target_cell.value = begin_time
                    target_cell = self.sheet_over.cell(column=7, row=eachcycle)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                    end_time = self.TestSummary.get('Cycle 1', f'Loop{eachcycle - 2}.EndDateTime')  # 第一圈开始时间对应Loop0.StartDateTime
                    target_cell.value = end_time
                self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                target_cell = self.sheet_device.cell(column=1, row=1)
                target_cell.value = 'No'
                target_cell = self.sheet_device.cell(column=2, row=1)
                target_cell.value = 'State'
                target_cell = self.sheet_device.cell(column=3, row=1)
                target_cell.value = 'Name'
                row=2#从第2行还是写
                for section in self.devicestatus.sections():#获取每一个section名称和section整体， 下面any内置函数代表如果列表里的元组如果第一个元素有failcount,代表这个section设备fail,等价于for item in self.devicestatus.items(section):,if item[0]=='failurecount':, item代表这个section的其中一个键值对('classdescription', 'Software components')元组格式
                    if any(item[0] == 'failurecount' for item in self.devicestatus.items(section)):# self.devicestatus.items(section)返回列表，列表里是元组，元组是该section里的每一个键值对[('devicename', 'Intel(R) Graphics Command Center'), ('classdescription', 'Software components')，('failurecount', '2')]
                        fail_device_name = (self.devicestatus[f'{section}']['devicename'])
                        fail_device_cycle = (self.devicestatus[f'{section}']['failurecycleLoops'])##返回 C1L1=N, C1L2=N字符串
                        fail_device_cycle_list = fail_device_cycle.split(', ')  #转为列表['C1L1=N','C1L2=N']
                        cycles= []  # 为了存储所有fail的圈数例如[1,2,3]
                        for i in fail_device_cycle_list:
                            match = re.search(r'L(\d+)=', i)#匹配L和=之间的数字，\d 匹配任意数字(0-9)，+ 表示匹配前面的元素一次或多次
                            cycle = match.group(1)  # 返回数字但是是字符串格式,a='shjL109=N'，mat=re.search(r'L(\d+)=',a),print(mat[0]) mat[0]返回L109=完整内容，mat[1]返回数字。就是括号部分(\d+)
                            cycles.append(cycle)
                        for each_cycle in cycles:
                            target_cell = self.sheet_device.cell(column=3, row=row)  # 从第2行还是写
                            target_cell.value = fail_device_name
                            if fail_device_cycle_list[0][-1] == 'N':  #['C1L1=N','C1L2=N']
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'LOST'
                            elif fail_device_cycle_list[0][-1] == 'D':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'DISABLE'
                            elif fail_device_cycle_list[0][-1] == 'R' or fail_device_cycle_list[0][-1] == 'S':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'DIFF'
                            elif fail_device_cycle_list[0][-1] == 'P':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'YB'
                            target_cell = self.sheet_device.cell(column=1, row=row)  # 从第2行还是写
                            target_cell.value =each_cycle
                            row = row + 1#下次就要填在第三行
                self.device_check_total.save(os.path.join(self.current_tool_path, 'device_check_total.xlsx'))

        elif self.TestSummary.has_option('Cycle 1', 'JobResult') and self.TestSummary.get('Cycle 1','JobResult')=='ABORT':#代表中途自己点abort的，自己终止的，不用收log，代表要重来、
            pass
        elif self.TestSummary.has_option('Cycle 1', 'JobResult') and self.TestSummary.get('Cycle 1','JobResult')=='FAIL' and not self.TestSummary.has_option('Cycle 1', maxloopresult):#代表JobResult=FAIL脚本结果呈现fail，且没有最大圈数的结果出现，代表就是stopon on fail
            loop_list = []  # 用来装['loop0.result', 'loop1.result', 'loop2.result']
            for key in self.TestSummary['Cycle 1']:  # 遍历配置文件的键
                if key.startswith('loop') and key.endswith('result'):  # 找到以 "Loop" 开头且以 "Result" 结尾的键，，，`configparser` 模块在读取配置时，默认会将每个选项（键）转换为小写形式，但不会改变选项对应的值（即等号右边的部分）的大小写。所以这里用小写，即使读值的时候我虽然写的大写，实际也是按小写去找的例如get('Cycle 1','JobResult')，实际按get('Cycle 1','jobresult')去找的
                    loop_list.append(key)
            target_cell = self.sheet_over.cell(column=1, row=1)
            target_cell.value = 'Subitem'
            target_cell = self.sheet_over.cell(column=2, row=1)
            target_cell.value = 'No'
            target_cell = self.sheet_over.cell(column=3, row=1)
            target_cell.value = 'State'
            target_cell = self.sheet_over.cell(column=4, row=1)
            target_cell.value = 'ErrorCode'
            target_cell = self.sheet_over.cell(column=5, row=1)
            target_cell.value = 'ErrorDesc'
            target_cell = self.sheet_over.cell(column=6, row=1)
            target_cell.value = 'Begin'
            target_cell = self.sheet_over.cell(column=7, row=1)
            target_cell.value = 'End'
            target_cell = self.sheet_device.cell(column=1, row=1)
            target_cell.value = 'No'
            target_cell = self.sheet_device.cell(column=2, row=1)
            target_cell.value = 'State'
            target_cell = self.sheet_device.cell(column=3, row=1)
            target_cell.value = 'Name'
            if len(loop_list)==2:#loop0和loop1,代表第一圈fail，从第2行开始写，如果looplist 长度为2（stop on fail 至少长度为2，因为loop0始终pass），就是loop0和loop1, loop1=fail,第一圈fail
                target_cell = self.sheet_over.cell(column=1, row=2)  # 第一列写PM类型
                target_cell.value = self.info.get('config', 'pmclass')
                target_cell = self.sheet_over.cell(column=2, row=2)  # 第二列写cycle圈数，第一圈开始
                target_cell.value = '1'
                target_cell = self.sheet_over.cell(column=3, row=2)  # 第三列写结果，
                target_cell.value = 'FAIL'
                target_cell = self.sheet_over.cell(column=4, row=2)
                target_cell.value = '0x002761'
                target_cell = self.sheet_over.cell(column=5, row=2)
                target_cell.value = 'AbnormalEquipmentStatus'
                target_cell = self.sheet_over.cell(column=6, row=2)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                begin_time = self.TestSummary.get('Cycle 1', 'Loop0.StartDateTime')  # 第一圈开始时间对应Loop0.StartDateTime
                target_cell.value = begin_time
                target_cell = self.sheet_over.cell(column=7, row=2)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                end_time = self.TestSummary.get('Cycle 1', 'Loop0.EndDateTime')
                target_cell.value = end_time
                self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                row=2
                for section in self.devicestatus.sections():
                    if any(item[0] == 'failurecount' for item in self.devicestatus.items(section)):
                        fail_device_name = (self.devicestatus[f'{section}']['devicename'])
                        fail_device_cycle = (self.devicestatus[f'{section}']['failurecycleLoops'])##返回 C1L1=N, C1L2=N字符串
                        fail_device_cycle_list = fail_device_cycle.split(', ')  #转为列表['C1L1=N','C1L2=N']
                        cycles= []  # 为了存储所有fail的圈数例如[1,2,3]
                        for i in fail_device_cycle_list:
                            match = re.search(r'L(\d+)=', i)#匹配L和=之间的数字
                            cycle = match.group(1)  # 返回数字但是是字符串格式,a='shjL109=N'，mat=re.search(r'L(\d+)=',a),print(mat[0]) 0返回L109=，1返回数字。就是括号部分
                            cycles.append(cycle)
                        for each_cycle in cycles:
                            target_cell = self.sheet_device.cell(column=3, row=row)  # 从第2行还是写
                            target_cell.value = fail_device_name
                            if fail_device_cycle_list[0][-1] == 'N':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'LOST'
                            elif fail_device_cycle_list[0][-1] == 'D':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'DISABLE'
                            elif fail_device_cycle_list[0][-1] == 'R' or fail_device_cycle_list[0][-1] == 'S':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'DIFF'
                            elif fail_device_cycle_list[0][-1] == 'P':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'YB'
                            target_cell = self.sheet_device.cell(column=1, row=row)  # 从第2行还是写
                            target_cell.value =each_cycle
                            row = row + 1#下次就要填在第三行
                self.device_check_total.save(os.path.join(self.current_tool_path, 'device_check_total.xlsx'))
            else:#looplist长度至少为3，就是loop0和loop1,loop2, loop2=fail,第2圈fail,长度-2以及之前的圈数都pass, 如果长度为5，就是0到4result,5-2也就是3圈之前都pass,4圈fail符合公式逻辑
                row=2
                for eachcycle in range(0, len(loop_list)-2):#从第2行开始写
                    target_cell = self.sheet_over.cell(column=1, row=row)  # 第一列写PM类型
                    target_cell.value = self.info.get('config', 'pmclass')
                    target_cell = self.sheet_over.cell(column=2, row=row)  # 第二列写cycle圈数，第一圈开始
                    target_cell.value = str(eachcycle+1)
                    target_cell = self.sheet_over.cell(column=3, row=row)  # 第三列写结果，
                    target_cell.value = 'PASS'
                    target_cell = self.sheet_over.cell(column=6, row=row)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                    begin_time = self.TestSummary.get('Cycle 1', f'Loop{eachcycle}.StartDateTime')  # 第一圈开始时间对应Loop0.StartDateTime
                    target_cell.value = begin_time
                    target_cell = self.sheet_over.cell(column=7, row=row)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                    end_time = self.TestSummary.get('Cycle 1', f'Loop{eachcycle}.EndDateTime')  # 第一圈开始时间对应Loop0.StartDateTime
                    target_cell.value = end_time
                    row=row+1
                target_cell = self.sheet_over.cell(column=1, row=row)  # 第一列写PM类型
                target_cell.value = self.info.get('config', 'pmclass')
                target_cell = self.sheet_over.cell(column=2, row=row)  # 第二列写cycle圈数，第一圈开始
                target_cell.value = str(len(loop_list)-1)#长度是5就是loop4.result=fail， 第4圈设备有异常，检查fail，因为是stoponfail, 这里的loop4就真的是只跑了4圈，第4圈回来检查fail就终止了
                target_cell = self.sheet_over.cell(column=3, row=row)  # 第三列写结果，
                target_cell.value = 'FAIL'
                target_cell = self.sheet_over.cell(column=4, row=row)
                target_cell.value = '0x002761'
                target_cell = self.sheet_over.cell(column=5, row=row)
                target_cell.value = 'AbnormalEquipmentStatus'
                target_cell = self.sheet_over.cell(column=6, row=row)  
                begin_time = self.TestSummary.get('Cycle 1', f'Loop{str(len(loop_list)-1)}.StartDateTime')  # 第一圈开始时间对应Loop0.StartDateTime
                target_cell.value = begin_time
                target_cell = self.sheet_over.cell(column=7, row=row)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                end_time = self.TestSummary.get('Cycle 1', f'Loop{str(len(loop_list)-1)}.EndDateTime')  # 第一圈开始时间对应Loop0.StartDateTime
                target_cell.value = end_time
                self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                line=2
                for section in self.devicestatus.sections():  # 获取每一个section名称和section整体， 下面any内置函数代表如果列表里的元组如果第一个元素有failcount,代表这个设备fail#等价于for item in info.items(section):,if item[0]=='failurecount':
                    if any(item[0] == 'failurecount' for item in self.devicestatus.items(section)):  # self.devicestatus.items(section)返回列表，列表里是元组，元组是该section里的每一个键值对[('devicename', 'Intel(R) Graphics Command Center'), ('classdescription', 'Software components')]
                        fail_device_name = (self.devicestatus[f'{section}']['devicename'])
                        fail_device_cycle = (self.devicestatus[f'{section}']['failurecycleLoops'])  ##返回 C1L1=N, C1L2=N字符串
                        fail_device_cycle_list = fail_device_cycle.split(', ')  # 转为列表['C1L1=N','C1L2=N']
                        cycles = []  # 为了存储所有fail的圈数例如[1,2,3]
                        for i in fail_device_cycle_list:
                            match = re.search(r'L(\d+)=', i)  # 匹配L和=之间的数字
                            cycle = match.group(1)  # 返回数字但是是字符串格式,a='shjL109=N'，mat=re.search(r'L(\d+)=',a),print(mat[0]) 0返回L109=，1返回数字。就是括号部分
                            cycles.append(cycle)
                        for each_cycle in cycles:
                            target_cell = self.sheet_device.cell(column=3, row=line)  # 从第2行还是写
                            target_cell.value = fail_device_name
                            if fail_device_cycle_list[0][-1] == 'N':
                                target_cell = self.sheet_device.cell(column=2, row=line)
                                target_cell.value = 'LOST'
                            elif fail_device_cycle_list[0][-1] == 'D':
                                target_cell = self.sheet_device.cell(column=2, row=line)
                                target_cell.value = 'DISABLE'
                            elif fail_device_cycle_list[0][-1] == 'R' or fail_device_cycle_list[0][-1] == 'S':
                                target_cell = self.sheet_device.cell(column=2, row=line)
                                target_cell.value = 'DIFF'
                            elif fail_device_cycle_list[0][-1] == 'P':
                                target_cell = self.sheet_device.cell(column=2, row=line)
                                target_cell.value = 'YB'
                            target_cell = self.sheet_device.cell(column=1, row=line)  # 从第2行还是写
                            target_cell.value = each_cycle
                            line = line + 1  # 下次就要填在第三行
                self.device_check_total.save(os.path.join(self.current_tool_path, 'device_check_total.xlsx'))
        else: #代表没有抓到最大的圈数和最终的结果，肯定是中途有断，所以需要抓到当前log里最大圈数，然后根据附近的时间来导出差不多时间的event log来判断error
            loop_list=[]#用来装['loop0.result', 'loop1.result', 'loop2.result']
            for key in self.TestSummary['Cycle 1']:#遍历配置文件的键
                if key.startswith('loop') and key.endswith('result'):#找到以 "Loop" 开头且以 "Result" 结尾的键，，，`configparser` 模块在读取配置时，默认会将每个选项（键）转换为小写形式，但不会改变选项对应的值（即等号右边的部分）的大小写。所以这里用小写，实际读值的时候我虽然写的大写，实际也是按小写取找.get('Cycle 1','JobResult')
                    loop_list.append(key)
            if loop_list !=[]:#代表至少有抓到loop0,也就是跑完1圈，这时候及时是第一圈有YB或者其他设备异常，因为第二圈出现了黑屏等其他，导致loop1没生成，掉设备的结果没办法呈现在testsummary里，但这时候devicestatus里已经可以抓到第一圈设备异常的东西了
                begin_time_first_cycle = self.TestSummary.get('Cycle 1', 'Loop0.StartDateTime')#后面多个地方会用所以先定义一下，免得后面重复代码
                end_time_fisrt_cycle = self.TestSummary.get('Cycle 1', 'Loop0.EndDateTime')
                match = re.search(r'loop(\d+).result', loop_list[-1])  # 匹配loop和。result之间的数字,列表里的最后一项肯定跑到的是最大的圈数，['loop0.result', 'loop1.result', 'loop2.result']
                max_cycle= int(match.group(1))#知道了loop最大的圈数
                target_cell = self.sheet_device.cell(column=1, row=1)
                target_cell.value = 'No'
                target_cell = self.sheet_device.cell(column=2, row=1)
                target_cell.value = 'State'
                target_cell = self.sheet_device.cell(column=3, row=1)
                target_cell.value = 'Name'
                row = 2  # 从第2行还是写
                list_judge = []
                for section in self.devicestatus.sections():  # 获取每一个section名称和section整体， 下面any内置函数代表如果列表里的元组如果第一个元素有failcount,代表这个设备fail#等价于for item in info.items(section):,if item[0]=='failurecount':
                    if any(item[0] == 'failurecount' for item in self.devicestatus.items(section)):  # self.devicestatus.items(section)返回列表，列表里是元组，元组是该section里的每一个键值对[('devicename', 'Intel(R) Graphics Command Center'), ('classdescription', 'Software components')]
                        fail_device_name = (self.devicestatus[f'{section}']['devicename'])
                        fail_device_cycle = (self.devicestatus[f'{section}']['failurecycleLoops'])  ##返回 C1L1=N, C1L2=N字符串
                        fail_device_cycle_list = fail_device_cycle.split(', ')  # 转为列表['C1L1=N','C1L2=N']
                        cycles = []  # 为了存储所有fail的圈数例如[1,2,3]
                        for i in fail_device_cycle_list:
                            match1 = re.search(r'L(\d+)=', i)  # 匹配L和=之间的数字
                            cycle = match1.group(1)  # 返回数字但是是字符串格式,a='shjL109=N'，mat=re.search(r'L(\d+)=',a),print(mat[0]) 0返回L109=，1返回数字。就是括号部分
                            cycles.append(cycle)
                        for each_cycle in cycles:
                            target_cell = self.sheet_device.cell(column=3, row=row)  # 从第2行还是写
                            target_cell.value = fail_device_name
                            if fail_device_cycle_list[0][-1] == 'N':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'LOST'
                            elif fail_device_cycle_list[0][-1] == 'D':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'DISABLE'
                            elif fail_device_cycle_list[0][-1] == 'R' or fail_device_cycle_list[0][-1] == 'S':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'DIFF'
                            elif fail_device_cycle_list[0][-1] == 'P':
                                target_cell = self.sheet_device.cell(column=2, row=row)
                                target_cell.value = 'YB'
                            target_cell = self.sheet_device.cell(column=1, row=row)  # 从第2行还是写
                            target_cell.value = each_cycle
                            row = row + 1  # 下次就要填在第三行
                        list_judge.append('1')#代表device有找到fail
                self.device_check_total.save(os.path.join(self.current_tool_path, 'device_check_total.xlsx'))
                target_cell = self.sheet_over.cell(column=1, row=1)
                target_cell.value = 'Subitem'
                target_cell = self.sheet_over.cell(column=2, row=1)
                target_cell.value = 'No'
                target_cell = self.sheet_over.cell(column=3, row=1)
                target_cell.value = 'State'
                target_cell = self.sheet_over.cell(column=4, row=1)
                target_cell.value = 'ErrorCode'
                target_cell = self.sheet_over.cell(column=5, row=1)
                target_cell.value = 'ErrorDesc'
                target_cell = self.sheet_over.cell(column=6, row=1)
                target_cell.value = 'Begin'
                target_cell = self.sheet_over.cell(column=7, row=1)
                target_cell.value = 'End'
                if max_cycle == 0:#代表第一圈跑完有回来，回到到第二圈回来之间有异常，只有生成loop0.result
                    if not self.TestSummary.has_option('Cycle 1', 'Loop1.SleepDateTime'):#如果没有Loop1.SleepDateTime，代表第二圈没睡下去，算是第一圈内发生异常，即使device 已经check完，sumary这边也只算黑屏的统计，客人说的如果设备和黑屏同时sumary里统计严重黑屏的结果，device那边有可能有生成第一圈的device check结果，有可能没有，不影响，有就统计，没有就不统计，如果有fail没统计到，wiLR tool设计，检查设备之前发生异常，check 不到，可以解释
                        query_start_time= datetime.datetime.strptime(end_time_fisrt_cycle, "%Y-%m-%d %H:%M:%S")#把第一圈结束时间作为查询event log的开始时间，并且转为时间格式
                        query_start_time_word = query_start_time - datetime.timedelta(hours=8)#转为时间世界格式，前推8小时
                        str_wordtime = str(query_start_time_word)#再转为字符串，2025-06-03 03:43:25为了配合event view里面的世界时间格式
                        str_wordtime_start=str_wordtime[0:10] + 'T' + str_wordtime[11:] + ".0000000Z"#转为event view里面的世界时间格式2025-06-12T02:28:19.7601149Z   7601149是微秒范围是0000000到9999999，这里统一为0000000开始查询
                        current_time =datetime.datetime.utcnow().replace(microsecond=0)#直接获取当前系统的世界时间, 去掉微秒，因为默认是6为数字微妙，比如.760114， 和前面标准格式不匹配先去掉
                        str_current_time=str(current_time)#2025-06-12 08:49:59
                        str_wordtime_end=str_current_time[0:10] + 'T' + str_current_time[11:] + ".9999999Z"
                        command=f'''
    $startTime = "{str_wordtime_start}"
    $endTime = "{str_wordtime_end}"
    $query = "*[System[TimeCreated[@SystemTime>='$startTime' and @SystemTime<='$endTime']]]"
    wevtutil epl System "{self.current_tool_path}\\failpoint.evtx" /q:"$query" /ow:true
    '''
                        subprocess.run(["powershell", "-command", command])#执行powershell命令
                        while True:
                            if os.path.exists(os.path.join(self.current_tool_path, 'failpoint.evtx')):
                                break
                        event_id_all=[]
                        bugcheck_id=[]
                        with Evtx(os.path.join(self.current_tool_path, 'failpoint.evtx')) as log:
                            for record in log.records():  # record对应每一个事件
                                try:
                                    event_xml = record.xml()  # 转为xml格式
                                    root = ET.fromstring(event_xml)
                                    ns = {'ns': 'http://schemas.microsoft.com/win/2004/08/events/event'}  # 定义XML命名空间
                                    # 使用XPath查找EventID
                                    event_id_elem = root.find('.//ns:EventID', ns)  # EventID标签锁定
                                    event_id_all.append(event_id_elem.text)
                                    if event_id_elem.text=='41':
                                        bugcheck_elem = root.find('.//ns:Data[@Name="BugcheckCode"]', ns)  # 元素属性name为BugcheckCode的data标签
                                        bugcheck_elem_value = int(bugcheck_elem.text)  # 要么为0要么非0
                                        bugcheck_id.append(bugcheck_elem_value)
                                except Exception as e:
                                    continue
                        if '1074' in event_id_all and '41' not in event_id_all and '6008' not in event_id_all:#非预期正常重启
                            target_cell = self.sheet_over.cell(column=1, row=2)  # 第一列写PM类型
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=2)  # 第二列写cycle圈数，第一圈开始
                            target_cell.value = '1'  # 这里肯定是2，因为第二圈出问题
                            target_cell = self.sheet_over.cell(column=3, row=2)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=2)
                            target_cell.value = '0x002973'
                            target_cell = self.sheet_over.cell(column=5, row=2)
                            target_cell.value = 'UnexpectRebootSystem'
                            target_cell = self.sheet_over.cell(column=6, row=2)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                            target_cell.value = begin_time_first_cycle
                            target_cell = self.sheet_over.cell(column=7, row=2)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                            target_cell.value = end_time_fisrt_cycle
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                        elif len(bugcheck_id) > 0 and bugcheck_id[0] !=0:#肯定是蓝屏
                            sixteen=hex(bugcheck_id[0]).replace('x','X')#转16进制为客人要求的格式例如292转为0x124,转化为0X124大写的X为了匹配客人的表格
                            Describe_EN='Bsod'+sixteen#转为Bsod0X124
                            target_cell = self.sheet_over.cell(column=1, row=2)  # 第一列写PM类型
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=2)  # 第二列写cycle圈数，第一圈开始
                            target_cell.value = '1'  # 这里肯定是2，因为第二圈出问题
                            target_cell = self.sheet_over.cell(column=3, row=2)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=2)
                            try:
                                target_cell.value = error_code[Describe_EN]
                            except:#代表evnt ID 41里的bugcheck code没有在客人的44项的表格里
                                target_cell.value = 'stop code is out of range'
                            target_cell = self.sheet_over.cell(column=5, row=2)
                            target_cell.value = Describe_EN
                            target_cell = self.sheet_over.cell(column=6, row=2)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                            target_cell.value = begin_time_first_cycle
                            target_cell = self.sheet_over.cell(column=7, row=2)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                            target_cell.value = end_time_fisrt_cycle
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                        elif len(bugcheck_id) > 0 and bugcheck_id[0]==0:#肯定异常重启H说的部等于就归纳到异常重启
                            target_cell = self.sheet_over.cell(column=1, row=2)  # 第一列写PM类型
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=2)  # 第二列写cycle圈数，第一圈开始
                            target_cell.value = '1'  # 这里肯定是2，因为第二圈出问题
                            target_cell = self.sheet_over.cell(column=3, row=2)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=2)
                            target_cell.value = '0x002758'
                            target_cell = self.sheet_over.cell(column=5, row=2)
                            target_cell.value = 'AbnormalShutdown'
                            target_cell = self.sheet_over.cell(column=6, row=2)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                            target_cell.value = begin_time_first_cycle
                            target_cell = self.sheet_over.cell(column=7, row=2)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                            target_cell.value = end_time_fisrt_cycle
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                    else:#代表第二圈有睡下去了没回来，第一圈根据前面device check list judge来判断是不是pass
                        target_cell = self.sheet_over.cell(column=1, row=2)  # 第一列写PM类型
                        target_cell.value = self.info.get('config', 'pmclass')
                        target_cell = self.sheet_over.cell(column=2, row=2)  # 第二列写cycle圈数，第一圈开始
                        target_cell.value = '1'
                        if list_judge==[]:#代表第一圈pass
                            target_cell = self.sheet_over.cell(column=3, row=2)  # 第三列写结果，
                            target_cell.value = 'PASS'
                        else:
                            target_cell = self.sheet_over.cell(column=3, row=2)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=2)
                            target_cell.value = '0x002761'
                            target_cell = self.sheet_over.cell(column=5, row=2)
                            target_cell.value = 'AbnormalEquipmentStatus'
                        target_cell = self.sheet_over.cell(column=6, row=2)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                        target_cell.value = begin_time_first_cycle
                        target_cell = self.sheet_over.cell(column=7, row=2)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                        target_cell.value = end_time_fisrt_cycle
                        #接下来填第二圈结果
                        query_start_time = datetime.datetime.strptime(end_time_fisrt_cycle, "%Y-%m-%d %H:%M:%S")  # 把第一圈结束时间作为查询event log的开始时间，并且转为时间格式
                        query_start_time_word = query_start_time - datetime.timedelta(hours=8)  # 转为时间世界格式，前推8小时
                        str_wordtime = str(query_start_time_word)  # 再转为字符串，2025-06-03 03:43:25为了配合event view里面的世界时间格式
                        str_wordtime_start = str_wordtime[0:10] + 'T' + str_wordtime[11:] + ".0000000Z"  # 转为event view里面的世界时间格式2025-06-12T02:28:19.7601149Z   7601149是微秒范围是0000000到9999999，这里统一为0000000开始查询
                        current_time = datetime.datetime.utcnow().replace(microsecond=0)  # 直接获取当前系统的世界时间, 去掉微秒，因为默认是6为数字微妙，比如.760114， 和前面标准格式不匹配先去掉
                        str_current_time = str(current_time)  # 2025-06-12 08:49:59
                        str_wordtime_end = str_current_time[0:10] + 'T' + str_current_time[11:] + ".9999999Z"
                        command = f'''
                           $startTime = "{str_wordtime_start}"
                           $endTime = "{str_wordtime_end}"
                           $query = "*[System[TimeCreated[@SystemTime>='$startTime' and @SystemTime<='$endTime']]]"
                           wevtutil epl System "{self.current_tool_path}\\failpoint.evtx" /q:"$query" /ow:true
                           '''
                        subprocess.run(["powershell", "-command", command])  # 执行powershell命令
                        while True:
                            if os.path.exists(os.path.join(self.current_tool_path, 'failpoint.evtx')):
                                break
                        event_id_all = []
                        bugcheck_id = []
                        with Evtx(os.path.join(self.current_tool_path, 'failpoint.evtx')) as log:
                            for record in log.records():  # record对应每一个事件
                                try:
                                    event_xml = record.xml()  # 转为xml格式
                                    root = ET.fromstring(event_xml)
                                    ns = {'ns': 'http://schemas.microsoft.com/win/2004/08/events/event'}  # 定义XML命名空间
                                    # 使用XPath查找EventID
                                    event_id_elem = root.find('.//ns:EventID', ns)  # EventID标签锁定
                                    event_id_all.append(event_id_elem.text)
                                    if event_id_elem.text == '41':
                                        bugcheck_elem = root.find('.//ns:Data[@Name="BugcheckCode"]',
                                                                  ns)  # 元素属性name为BugcheckCode的data标签
                                        bugcheck_elem_value = int(bugcheck_elem.text)  # 要么为0要么非0
                                        bugcheck_id.append(bugcheck_elem_value)
                                except Exception as e:
                                    continue
                        if '1074' in event_id_all and '41' not in event_id_all and '6008' not in event_id_all:  # 非预期正常重启
                            target_cell = self.sheet_over.cell(column=1, row=3)  # 第一列写PM类型
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=3)  # 第二列写cycle圈数，第一圈开始
                            target_cell.value = '2'  # 这里肯定是2，因为第二圈出问题
                            target_cell = self.sheet_over.cell(column=3, row=3)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=3)
                            target_cell.value = '0x002973'
                            target_cell = self.sheet_over.cell(column=5, row=3)
                            target_cell.value = 'UnexpectRebootSystem'
                            begin_time_second_cycle = self.TestSummary.get('Cycle 1', 'Loop1.StartDateTime')
                            target_cell = self.sheet_over.cell(column=6, row=3)  # 第6列写第2圈开始时间对应Loop1.StartDateTime
                            target_cell.value = begin_time_second_cycle
                            try:# 这里多半没有生成loop1.EndDateTimes所以用try，前面开始时间肯定生成了，因为都有sleepdate.time了
                                end_time_second_cycle = self.TestSummary.get('Cycle 1', 'Loop1.EndDateTime')
                                target_cell = self.sheet_over.cell(column=7, row=3)  # 第7列写第2圈结束时间对应Loop1.EndDateTime
                                target_cell.value = end_time_second_cycle
                            except:
                                pass
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                        elif len(bugcheck_id) > 0 and bugcheck_id[0] != 0:  # 肯定是蓝屏
                            sixteen = hex(bugcheck_id[0]).replace('x', 'X')  # 转16进制为客人要求的格式例如292转为0x124,转化为0X124大写的X为了匹配客人的表格
                            Describe_EN = 'Bsod' + sixteen  # 转为Bsod0X124
                            target_cell = self.sheet_over.cell(column=1, row=3)  # 第一列写PM类型
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=3)  # 第二列写cycle圈数，第一圈开始
                            target_cell.value = '2'  # 这里肯定是2，因为第二圈出问题
                            target_cell = self.sheet_over.cell(column=3, row=3)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=3)
                            try:
                                target_cell.value = error_code[Describe_EN]
                            except:  # 代表evnt ID 41里的bugcheck code没有在客人的44项的表格里
                                target_cell.value = 'stop code is out of range'
                            target_cell = self.sheet_over.cell(column=5, row=3)
                            target_cell.value = Describe_EN
                            begin_time_second_cycle = self.TestSummary.get('Cycle 1', 'Loop1.StartDateTime')
                            target_cell = self.sheet_over.cell(column=6, row=3) 
                            target_cell.value = begin_time_second_cycle
                            try:
                                end_time_second_cycle = self.TestSummary.get('Cycle 1', 'Loop1.EndDateTime')
                                target_cell = self.sheet_over.cell(column=7, row=3)  
                                target_cell.value = end_time_second_cycle
                            except:
                                pass

                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                        elif len(bugcheck_id) > 0 and bugcheck_id[0] == 0:  # 肯定异常重启H说的部等于就归纳到异常重启
                            target_cell = self.sheet_over.cell(column=1, row=3)  # 第一列写PM类型
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=3)  # 第二列写cycle圈数，第一圈开始
                            target_cell.value = '2'  # 这里肯定是2，因为第二圈出问题
                            target_cell = self.sheet_over.cell(column=3, row=3)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=3)
                            target_cell.value = '0x002758'
                            target_cell = self.sheet_over.cell(column=5, row=3)
                            target_cell.value = 'AbnormalShutdown'
                            begin_time_second_cycle = self.TestSummary.get('Cycle 1', 'Loop1.StartDateTime')
                            target_cell = self.sheet_over.cell(column=6, row=3)  
                            target_cell.value = begin_time_second_cycle
                            try:
                                end_time_second_cycle = self.TestSummary.get('Cycle 1', 'Loop1.EndDateTime')
                                target_cell = self.sheet_over.cell(column=7, row=3) 
                                target_cell.value = end_time_second_cycle
                            except:
                               pass
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                else:#至少有抓到loop0和loop1的result
                    for eachcycle in range(1, max_cycle+ 1):  #从第2行开始写，如果max是5代2表第6圈有回来，回来和第7圈睡下去这段时间异常，先把1到5圈的结果抄上去
                        target_cell = self.sheet_over.cell(column=1, row=eachcycle+1)  # 第一列写PM类型
                        target_cell.value = self.info.get('config', 'pmclass')
                        target_cell = self.sheet_over.cell(column=2, row=eachcycle+1)  # 第二列写cycle圈数，第一圈开始
                        target_cell.value = str(eachcycle)
                        target_cell = self.sheet_over.cell(column=3, row=eachcycle+1)  # 第三列写结果，
                        if self.TestSummary.get('Cycle 1', f'Loop{eachcycle}.Result') == 'FAIL':  
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=eachcycle+1)
                            target_cell.value = '0x002761'
                            target_cell = self.sheet_over.cell(column=5, row=eachcycle+1)
                            target_cell.value = 'AbnormalEquipmentStatus'
                        else:
                            target_cell.value = 'PASS'
                        target_cell = self.sheet_over.cell(column=6, row=eachcycle+1)  
                        begin_time = self.TestSummary.get('Cycle 1', f'Loop{eachcycle - 1}.StartDateTime')  
                        target_cell.value = begin_time
                        target_cell = self.sheet_over.cell(column=7, row=eachcycle+1)  
                        end_time = self.TestSummary.get('Cycle 1', f'Loop{eachcycle - 1}.EndDateTime')  
                        target_cell.value = end_time
                    # 接下来就要找到异常的一圈到底是什么原因了
                    if not self.TestSummary.has_option('Cycle 1', f'Loop{max_cycle+1}.SleepDateTime'):  # 代表下一圈没有睡下去，如果max是2，就是代表第三圈回来第4圈下去之前异常，算在第3圈，即使设备统计出来也有异常，sumary也统计为蓝屏黑屏，如果设备统计没统计出来第3圈的结果，代表是设备检查之前第3圈发生异常，自然统计不出来，逻辑也通，wiLR设计
                        query_start_time = datetime.datetime.strptime(self.TestSummary.get('Cycle 1', f'Loop{max_cycle}.EndDateTime'), "%Y-%m-%d %H:%M:%S")  # 把第3圈结束时间作为查询event log的开始时间，并且转为时间格式
                        query_start_time_word = query_start_time - datetime.timedelta(hours=8)  # 转为时间世界格式，前推8小时
                        str_wordtime = str(query_start_time_word)  # 再转为字符串，2025-06-03 03:43:25为了配合event view里面的世界时间格式
                        str_wordtime_start = str_wordtime[0:10] + 'T' + str_wordtime[11:] + ".0000000Z"  # 转为event view里面的世界时间格式2025-06-12T02:28:19.7601149Z   7601149是微秒范围是0000000到9999999，这里统一为0000000开始查询
                        current_time = datetime.datetime.utcnow().replace(microsecond=0)  # 直接获取当前系统的世界时间, 去掉微秒，因为默认是6为数字微妙，比如.760114， 和前面标准格式不匹配先去掉
                        str_current_time = str(current_time)  # 2025-06-12 08:49:59
                        str_wordtime_end = str_current_time[0:10] + 'T' + str_current_time[11:] + ".9999999Z"
                        command = f'''
                $startTime = "{str_wordtime_start}"
                $endTime = "{str_wordtime_end}"
                $query = "*[System[TimeCreated[@SystemTime>='$startTime' and @SystemTime<='$endTime']]]"
                wevtutil epl System "{self.current_tool_path}\\failpoint.evtx" /q:"$query" /ow:true
                '''
                        subprocess.run(["powershell", "-command", command])  # 执行powershell命令
                        while True:
                            if os.path.exists(os.path.join(self.current_tool_path, 'failpoint.evtx')):
                                break
                        event_id_all = []
                        bugcheck_id = []
                        with Evtx(os.path.join(self.current_tool_path, 'failpoint.evtx')) as log:
                            for record in log.records():  # record对应每一个事件
                                try:
                                    event_xml = record.xml()  # 转为xml格式
                                    root = ET.fromstring(event_xml)
                                    ns = {
                                        'ns': 'http://schemas.microsoft.com/win/2004/08/events/event'}  # 定义XML命名空间
                                    # 使用XPath查找EventID
                                    event_id_elem = root.find('.//ns:EventID', ns)  # EventID标签锁定
                                    event_id_all.append(event_id_elem.text)
                                    if event_id_elem.text == '41':
                                        bugcheck_elem = root.find('.//ns:Data[@Name="BugcheckCode"]',
                                                                  ns)  # 元素属性name为BugcheckCode的data标签
                                        bugcheck_elem_value = int(bugcheck_elem.text)  # 要么为0要么非0
                                        bugcheck_id.append(bugcheck_elem_value)
                                except Exception as e:
                                    continue
                        if '1074' in event_id_all and '41' not in event_id_all and '6008' not in event_id_all:  # 非预期正常重启
                            target_cell = self.sheet_over.cell(column=1, row=max_cycle+2)  # 第一列写PM类型
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=max_cycle+2)  # 第二列写cycle圈数
                            target_cell.value = str(max_cycle+1)  #如前面讨论的，max为2的话且无第三圈下去的标志，就是算3圈，所以2+1
                            target_cell = self.sheet_over.cell(column=3, row=max_cycle+2)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=max_cycle+2)
                            target_cell.value = '0x002973'
                            target_cell = self.sheet_over.cell(column=5, row=max_cycle+2)
                            target_cell.value = 'UnexpectRebootSystem'
                            start_time_last=self.TestSummary.get('Cycle 1', f'Loop{max_cycle}.StartDateTime')
                            target_cell = self.sheet_over.cell(column=6, row=max_cycle+2)
                            target_cell.value = start_time_last
                            end_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle}.EndDateTime')
                            target_cell = self.sheet_over.cell(column=7, row=max_cycle+2) 
                            target_cell.value = end_time_last
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                        elif len(bugcheck_id) > 0 and bugcheck_id[0] != 0:  # 肯定是蓝屏
                            sixteen = hex(bugcheck_id[0]).replace('x', 'X')  # 转16进制为客人要求的格式例如292转为0x124,转化为0X124大写的X为了匹配客人的表格
                            Describe_EN = 'Bsod' + sixteen  # 转为Bsod0X124
                            target_cell = self.sheet_over.cell(column=1, row=max_cycle + 2)  # 第一列写PM类型
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=max_cycle + 2)  # 第二列写cycle圈数，第一圈开始
                            target_cell.value = str(max_cycle+1)  # 这里肯定是2，因为第二圈出问题
                            target_cell = self.sheet_over.cell(column=3, row=max_cycle + 2)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=max_cycle + 2)
                            try:
                                target_cell.value = error_code[Describe_EN]
                            except:  # 代表evnt ID 41里的bugcheck code没有在客人的44项的表格里
                                target_cell.value = 'stop code is out of range'
                            target_cell = self.sheet_over.cell(column=5, row=max_cycle + 2)
                            target_cell.value = Describe_EN
                            start_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle}.StartDateTime')
                            target_cell = self.sheet_over.cell(column=6, row=max_cycle + 2)
                            target_cell.value = start_time_last
                            end_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle}.EndDateTime')
                            target_cell = self.sheet_over.cell(column=7, row=max_cycle + 2)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                            target_cell.value = end_time_last
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                        elif len(bugcheck_id) > 0 and bugcheck_id[0] == 0:  # 肯定异常重启H说的部等于就归纳到异常重启
                            target_cell = self.sheet_over.cell(column=1, row=max_cycle + 2)  # 第一列写PM类型
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=max_cycle + 2)  # 第二列写cycle圈数，第一圈开始
                            target_cell.value = str(max_cycle+1)  # 这里肯定是2，因为第二圈出问题
                            target_cell = self.sheet_over.cell(column=3, row=max_cycle + 2)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=max_cycle + 2)
                            target_cell.value = '0x002758'
                            target_cell = self.sheet_over.cell(column=5, row=max_cycle + 2)
                            target_cell.value = 'AbnormalShutdown'
                            start_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle}.StartDateTime')
                            target_cell = self.sheet_over.cell(column=6, row=max_cycle + 2)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                            target_cell.value = start_time_last
                            end_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle}.EndDateTime')
                            target_cell = self.sheet_over.cell(column=7, row=max_cycle + 2)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                            target_cell.value = end_time_last
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                    else:#代表下一圈有睡下去。max是2的话，代表3圈回来，4圈也有下去，只是4圈没回来，这时候第三圈肯定是有设备生成检查出来的，而且是进行第4圈，所以sumary要多填一圈结果
                        target_cell = self.sheet_over.cell(column=1, row=max_cycle + 2)  
                        target_cell.value = self.info.get('config', 'pmclass')
                        target_cell = self.sheet_over.cell(column=2, row=max_cycle + 2) 
                        target_cell.value = str(max_cycle + 1) 
                        if list_judge == []:  # 代表之前没有fail, 第3圈直接pass
                            target_cell = self.sheet_over.cell(column=3, row=max_cycle + 2)  # 第三列写结果，
                            target_cell.value = 'PASS'
                        else:
                            target_cell = self.sheet_over.cell(column=4, row=max_cycle + 2)
                            target_cell.value = '0x002761'
                            target_cell = self.sheet_over.cell(column=5, row=max_cycle + 2)
                            target_cell.value = 'AbnormalEquipmentStatus'
                        start_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle}.StartDateTime')
                        target_cell = self.sheet_over.cell(column=6, row=max_cycle + 2)  
                        target_cell.value = start_time_last
                        end_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle}.EndDateTime')
                        target_cell = self.sheet_over.cell(column=7, row=max_cycle + 2)  
                        target_cell.value = end_time_last
                        #接下来看第4圈异常的原因
                        query_start_time = datetime.datetime.strptime(self.TestSummary.get('Cycle 1', f'Loop{max_cycle}.EndDateTime'), "%Y-%m-%d %H:%M:%S")  # 把第max圈结束时间作为查询event log的开始时间，并且转为时间格式
                        query_start_time_word = query_start_time - datetime.timedelta(hours=8)  # 转为时间世界格式，前推8小时
                        str_wordtime = str(query_start_time_word)  # 再转为字符串，2025-06-03 03:43:25为了配合event view里面的世界时间格式
                        str_wordtime_start = str_wordtime[0:10] + 'T' + str_wordtime[11:] + ".0000000Z"  # 转为event view里面的世界时间格式2025-06-12T02:28:19.7601149Z   7601149是微秒范围是0000000到9999999，这里统一为0000000开始查询
                        current_time = datetime.datetime.utcnow().replace(microsecond=0)  # 直接获取当前系统的世界时间, 去掉微秒，因为默认是6为数字微妙，比如.760114， 和前面标准格式不匹配先去掉
                        str_current_time = str(current_time)  # 2025-06-12 08:49:59
                        str_wordtime_end = str_current_time[0:10] + 'T' + str_current_time[11:] + ".9999999Z"
                        command = f'''
                    $startTime = "{str_wordtime_start}"
                    $endTime = "{str_wordtime_end}"
                    $query = "*[System[TimeCreated[@SystemTime>='$startTime' and @SystemTime<='$endTime']]]"
                    wevtutil epl System "{self.current_tool_path}\\failpoint.evtx" /q:"$query" /ow:true
                    '''
                        subprocess.run(["powershell", "-command", command])  # 执行powershell命令
                        while True:
                            if os.path.exists(os.path.join(self.current_tool_path, 'failpoint.evtx')):
                                break
                        event_id_all = []
                        bugcheck_id = []
                        with Evtx(os.path.join(self.current_tool_path, 'failpoint.evtx')) as log:
                            for record in log.records():  # record对应每一个事件
                                try:
                                    event_xml = record.xml()  # 转为xml格式
                                    root = ET.fromstring(event_xml)
                                    ns = {'ns': 'http://schemas.microsoft.com/win/2004/08/events/event'}  # 定义XML命名空间
                                    # 使用XPath查找EventID
                                    event_id_elem = root.find('.//ns:EventID', ns)  # EventID标签锁定
                                    event_id_all.append(event_id_elem.text)
                                    if event_id_elem.text == '41':
                                        bugcheck_elem = root.find('.//ns:Data[@Name="BugcheckCode"]', ns)  # 元素属性name为BugcheckCode的data标签
                                        bugcheck_elem_value = int(bugcheck_elem.text)  # 要么为0要么非0
                                        bugcheck_id.append(bugcheck_elem_value)
                                except Exception as e:
                                    continue
                        if '1074' in event_id_all and '41' not in event_id_all and '6008' not in event_id_all:  # 非预期正常重启
                            target_cell = self.sheet_over.cell(column=1, row=max_cycle+3)  # 第一列写PM类型
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=max_cycle+3)  # 第二列写cycle圈数，第一圈开始
                            target_cell.value = str(max_cycle+2)  #
                            target_cell = self.sheet_over.cell(column=3, row=max_cycle+3)  # 第三列写结果，
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=max_cycle+3)
                            target_cell.value = '0x002973'
                            target_cell = self.sheet_over.cell(column=5, row=max_cycle+3)
                            target_cell.value = 'UnexpectRebootSystem'
                            begin_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle+1}.StartDateTime')
                            target_cell = self.sheet_over.cell(column=6, row=max_cycle+3) 
                            target_cell.value = begin_time_last
                            try:
                                end_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle + 1}.EndDateTime')
                                target_cell = self.sheet_over.cell(column=7, row=max_cycle + 3)  #
                                target_cell.value = end_time_last
                            except:
                                pass
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                        elif len(bugcheck_id) > 0 and bugcheck_id[0] != 0:  # 肯定是蓝屏
                            sixteen = hex(bugcheck_id[0]).replace('x', 'X')  # 转16进制为客人要求的格式例如292转为0x124,转化为0X124大写的X为了匹配客人的表格
                            Describe_EN = 'Bsod' + sixteen  # 转为Bsod0X124
                            target_cell = self.sheet_over.cell(column=1, row=max_cycle+3)  
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=max_cycle+3)  
                            target_cell.value = str(max_cycle+2)
                            target_cell = self.sheet_over.cell(column=3, row=max_cycle+3)  
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=max_cycle+3)
                            try:
                                target_cell.value = error_code[Describe_EN]
                            except:  # 代表evnt ID 41里的bugcheck code没有在客人的44项的表格里
                                target_cell.value = 'stop code is out of range'
                            target_cell = self.sheet_over.cell(column=5, row=max_cycle+2)
                            target_cell.value = Describe_EN
                            begin_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle + 1}.StartDateTime')
                            target_cell = self.sheet_over.cell(column=6, row=max_cycle + 3)
                            target_cell.value = begin_time_last
                            try:
                                end_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle + 1}.EndDateTime')
                                target_cell = self.sheet_over.cell(column=7, row=max_cycle + 3)
                                target_cell.value = end_time_last
                            except:
                                pass
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                        elif len(bugcheck_id) > 0 and bugcheck_id[0] == 0:  
                            target_cell = self.sheet_over.cell(column=1, row=max_cycle+3)  
                            target_cell.value = self.info.get('config', 'pmclass')
                            target_cell = self.sheet_over.cell(column=2, row=max_cycle+3)  
                            target_cell.value = str(max_cycle+2) 
                            target_cell = self.sheet_over.cell(column=3, row=max_cycle+3)  
                            target_cell.value = 'FAIL'
                            target_cell = self.sheet_over.cell(column=4, row=max_cycle+3)
                            target_cell.value = '0x002758'
                            target_cell = self.sheet_over.cell(column=5, row=max_cycle+3)
                            target_cell.value = 'AbnormalShutdown'
                            begin_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle + 1}.StartDateTime')
                            target_cell = self.sheet_over.cell(column=6, row=max_cycle + 3)
                            target_cell.value = begin_time_last
                            try:
                                end_time_last = self.TestSummary.get('Cycle 1', f'Loop{max_cycle + 1}.EndDateTime')
                                target_cell = self.sheet_over.cell(column=7, row=max_cycle + 3)  
                                target_cell.value = end_time_last
                            except:
                                pass
                            self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
            else:  # 就是loop0都没收到结果，第一圈就出问题，device部分直接不用填，直接看考虑蓝屏异常重启关机. 直接抓loop0 start time
                target_cell = self.sheet_device.cell(column=1, row=2)
                target_cell.value = 'No'
                target_cell = self.sheet_device.cell(column=2, row=2)
                target_cell.value = 'State'
                target_cell = self.sheet_device.cell(column=3, row=2)
                target_cell.value = 'Name'
                self.device_check_total.save(os.path.join(self.current_tool_path, 'device_check_total.xlsx'))
                query_start_time = datetime.datetime.strptime(self.TestSummary.get('Cycle 1', f'Loop0.StartDateTime'), "%Y-%m-%d %H:%M:%S")  # 把第max圈结束时间作为查询event log的开始时间，并且转为时间格式
                query_start_time_word = query_start_time - datetime.timedelta(hours=8)  # 转为时间世界格式，前推8小时
                str_wordtime = str(query_start_time_word)  # 再转为字符串，2025-06-03 03:43:25为了配合event view里面的世界时间格式
                str_wordtime_start = str_wordtime[0:10] + 'T' + str_wordtime[11:] + ".0000000Z"  # 转为event view里面的世界时间格式2025-06-12T02:28:19.7601149Z   7601149是微秒范围是0000000到9999999，这里统一为0000000开始查询
                current_time = datetime.datetime.utcnow().replace(microsecond=0)  # 直接获取当前系统的世界时间, 去掉微秒，因为默认是6为数字微妙，比如.760114， 和前面标准格式不匹配先去掉
                str_current_time = str(current_time)  # 2025-06-12 08:49:59
                str_wordtime_end = str_current_time[0:10] + 'T' + str_current_time[11:] + ".9999999Z"
                command = f'''
                                 $startTime = "{str_wordtime_start}"
                                 $endTime = "{str_wordtime_end}"
                                 $query = "*[System[TimeCreated[@SystemTime>='$startTime' and @SystemTime<='$endTime']]]"
                                 wevtutil epl System "{self.current_tool_path}\\failpoint.evtx" /q:"$query" /ow:true
                                 '''
                subprocess.run(["powershell", "-command", command])  # 执行powershell命令
                while True:
                    if os.path.exists(os.path.join(self.current_tool_path, 'failpoint.evtx')):
                        break
                event_id_all = []
                bugcheck_id = []
                with Evtx(os.path.join(self.current_tool_path, 'failpoint.evtx')) as log:
                    for record in log.records():  # record对应每一个事件
                        try:
                            event_xml = record.xml()  # 转为xml格式
                            root = ET.fromstring(event_xml)
                            ns = {'ns': 'http://schemas.microsoft.com/win/2004/08/events/event'}  # 定义XML命名空间
                            # 使用XPath查找EventID
                            event_id_elem = root.find('.//ns:EventID', ns)  # EventID标签锁定
                            event_id_all.append(event_id_elem.text)
                            if event_id_elem.text == '41':
                                bugcheck_elem = root.find('.//ns:Data[@Name="BugcheckCode"]', ns)  # 元素属性name为BugcheckCode的data标签
                                bugcheck_elem_value = int(bugcheck_elem.text)  # 要么为0要么非0
                                bugcheck_id.append(bugcheck_elem_value)
                        except Exception as e:
                            continue
                if '1074' in event_id_all and '41' not in event_id_all and '6008' not in event_id_all:  # 非预期正常重启
                    target_cell = self.sheet_over.cell(column=1, row=2)  # 第一列写PM类型
                    target_cell.value = self.info.get('config', 'pmclass')
                    target_cell = self.sheet_over.cell(column=2, row=2)  # 第二列写cycle圈数，第一圈开始
                    target_cell.value = '1'  #
                    target_cell = self.sheet_over.cell(column=3, row=2)  # 第三列写结果，
                    target_cell.value = 'FAIL'
                    target_cell = self.sheet_over.cell(column=4, row=2)
                    target_cell.value = '0x002973'
                    target_cell = self.sheet_over.cell(column=5, row=2)
                    target_cell.value = 'UnexpectRebootSystem'
                    begin_time_cycle = self.TestSummary.get('Cycle 1', 'Loop0.StartDateTime')
                    target_cell = self.sheet_over.cell(column=6, row=2)  #
                    target_cell.value = begin_time_cycle
                    try:
                        end_time_cycle = self.TestSummary.get('Cycle 1', 'Loop0.EndDateTime')
                        target_cell = self.sheet_over.cell(column=7, row=2)
                        target_cell.value = end_time_cycle
                    except:
                        pass
                    self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                elif len(bugcheck_id) > 0 and bugcheck_id[0] != 0:  # 肯定是蓝屏
                    sixteen = hex(bugcheck_id[0]).replace('x', 'X')  # 转16进制为客人要求的格式例如292转为0x124,转化为0X124大写的X为了匹配客人的表格
                    Describe_EN = 'Bsod' + sixteen  # 转为Bsod0X124
                    target_cell = self.sheet_over.cell(column=1, row=2)  # 第一列写PM类型
                    target_cell.value = self.info.get('config', 'pmclass')
                    target_cell = self.sheet_over.cell(column=2, row=2)  #
                    target_cell.value = '1' 
                    target_cell = self.sheet_over.cell(column=3, row=2)  # 第三列写结果，
                    target_cell.value = 'FAIL'
                    target_cell = self.sheet_over.cell(column=4, row=2)
                    try:
                        target_cell.value = error_code[Describe_EN]
                    except:  # 代表evnt ID 41里的bugcheck code没有在客人的44项的表格里
                        target_cell.value = 'stop code is out of range'
                    target_cell = self.sheet_over.cell(column=5, row=2)
                    target_cell.value = Describe_EN
                    begin_time_cycle = self.TestSummary.get('Cycle 1', 'Loop0.StartDateTime')
                    target_cell = self.sheet_over.cell(column=6, row=2)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                    target_cell.value = begin_time_cycle
                    try:
                        end_time_cycle = self.TestSummary.get('Cycle 1', 'Loop0.EndDateTime')
                        target_cell = self.sheet_over.cell(column=7, row=2)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                        target_cell.value = end_time_cycle
                    except:
                        pass
                    self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
                elif len(bugcheck_id) > 0 and bugcheck_id[0] == 0:
                    target_cell = self.sheet_over.cell(column=1, row=2)  # 第一列写PM类型
                    target_cell.value = self.info.get('config', 'pmclass')
                    target_cell = self.sheet_over.cell(column=2, row=2)  #
                    target_cell.value = '1'  #
                    target_cell = self.sheet_over.cell(column=3, row=2)  # 第三列写结果，
                    target_cell.value = 'FAIL'
                    target_cell = self.sheet_over.cell(column=4, row=2)
                    target_cell.value = '0x002758'
                    target_cell = self.sheet_over.cell(column=5, row=2)
                    target_cell.value = 'AbnormalShutdown'
                    begin_time_cycle = self.TestSummary.get('Cycle 1', 'Loop0.StartDateTime')
                    target_cell = self.sheet_over.cell(column=6, row=2)  # 第6列写第一圈开始时间对应Loop0.StartDateTime
                    target_cell.value = begin_time_cycle
                    try:
                        end_time_cycle = self.TestSummary.get('Cycle 1', 'Loop0.EndDateTime')
                        target_cell = self.sheet_over.cell(column=7, row=2)  # 第7列写第一圈结束时间对应Loop0.EndDateTime
                        target_cell.value = end_time_cycle
                    except:
                        pass
                    self.overview_result.save(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
    def xsl_to_csv(self):
        parent_dir = os.path.dirname(self.current_tool_path)#获取上一层路径
        wb = openpyxl.load_workbook(os.path.join(self.current_tool_path, 'overview_result.xlsx'))
        sheet = wb.active  # 获取当前活动的工作表
        with open(f"{parent_dir}\Result\{self.info.get('config','nowtime')}\overview_result.csv", 'w', newline='', encoding='utf-8') as csvfile:# 创建 CSV 文件并写入数据
            writer = csv.writer(csvfile)
            for row in sheet.iter_rows(values_only=True):  # 逐行读取数据
                writer.writerow(row)
        wb = openpyxl.load_workbook(os.path.join(self.current_tool_path, 'device_check_total.xlsx'))
        sheet = wb.active  # 获取当前活动的工作表
        with open(f"{parent_dir}\Result\{self.info.get('config','nowtime')}\device_check_total.csv", 'w', newline='', encoding='utf-8-sig') as csvfile:  # 创建 CSV 文件并写入数据
            writer = csv.writer(csvfile)
            for row in sheet.iter_rows(values_only=True):  # 逐行读取数据
                writer.writerow(row)
if __name__=="__main__":
    a=log()
    a.log_standard()
    a.xsl_to_csv()







